package com.moonshineproject.plugin.actionscript.as3parser.vo
{
	import __AS3__.vec.Vector;
	
	[RemoteClass(alias="v1.PackageVO")]
	public class PackageVO
	{
		public var name:String;
		
		public var packages:Vector.<PackageVO> = new Vector.<PackageVO>();
		public var classes:Vector.<ClassVO> = new Vector.<ClassVO>();

		public var packageName:String;

		public function getPackage(name:String):PackageVO
		{
			for (var i:int = 0; i < packages.length; i++)
			{
				if (packages[i].name == name) return packages[i];
			}
			
			return null;
		}

		public function getFullyQualifiedName():String
		{
			if (packageName)
			{
				return packageName + "." +name;
			}
			
			return name;
		}

		// IF you give a package name it will search from THIS package
		//   you may omit the package if the class is in this package 
		public function getClass(fullyQualifiedClassname:String):ClassVO
		{
			var className:String;
			var pkg:PackageVO = this;
			
			var split:Array = fullyQualifiedClassname.split(".");
			className = split[split.length-1];
			
			split = split.slice(0, -1);
			for each (var part:String in split)
			{
				pkg = pkg.getPackage(part);
				if (!pkg) return null;
			}
			
			return pkg.getClassByName(className);
		}

		public function merge(toMerge:PackageVO):void
		{
			// Merge in packages
			for each (var pkgToMerge:PackageVO in toMerge.packages)
			{
				var pkg:PackageVO = getPackage(pkgToMerge.name); 
				if (pkg)
				{
					pkg.merge(pkgToMerge);
				}
				else
				{
					packages.push(pkgToMerge);// = packages.concat(pkgToMerge.packages);
				}
			}
			
			// Merge in classes (don't look for conflicts)
			classes = classes.concat(toMerge.classes);
		}

		public function createPackage(name:String):PackageVO
		{
			var p:PackageVO = new PackageVO();
			p.name = name;
			p.packageName = getFullyQualifiedName();
			packages.push(p);
			
			return p;
		}
		
		public function addClass(c:ClassVO):void
		{
			c.packageName = getFullyQualifiedName();
			classes.push(c);
		}
		
		public function getTypes(recurseDown:Boolean=false):Vector.<ClassVO>
		{
			var toRet:Vector.<ClassVO> = this.classes;
			
			if (recurseDown)
			{
				for (var i:int = 0; i < this.packages.length; i++)
				{
					toRet = toRet.concat(this.packages[i].getTypes(true));
				}
			}
			return toRet;
		}
		
		protected function getClassByName(name:String):ClassVO
		{
			for (var i:int = 0; i < classes.length; i++)
			{
				if (classes[i].name == name) 
					return classes[i];
			}
			
			return null;
		}

	}
}